<?php
class APIHandler {
    private $api_base_url;
    private $api_key;
    private $pdo;
    private $user_ip;
    private $lang;
    private $selected_model;

    public function __construct($api_base_url, $api_key, $pdo, $lang = 'en', $selected_model = 'gpt-3.5-turbo') {
        $this->api_base_url = $api_base_url;
        $this->api_key = $api_key;
        $this->pdo = $pdo;
        $this->user_ip = $this->sanitizeIp($_SERVER['REMOTE_ADDR'] ?? 'unknown');
        $this->lang = $lang;
        $this->selected_model = $selected_model;
        $this->ensureUserDirExists();
    }

    private function sanitizeIp($ip) {
        // Remove any invalid characters and ensure we have a proper IP format
        // For IPv6 addresses, we'll normalize them to a consistent format
        // For IPv4 addresses, we'll ensure they're in the standard format
        $ip = trim($ip);
        
        // If the IP is behind a proxy, extract the real IP
        if (strpos($ip, ',') !== false) {
            $ips = array_map('trim', explode(',', $ip));
            $ip = $ips[0]; // Use the first IP in the list
        }
        
        // Validate and sanitize the IP
        if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) === false) {
            // If the IP is private or reserved, check for HTTP_X_FORWARDED_FOR or HTTP_X_REAL_IP
            $forwarded_ip = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['HTTP_X_REAL_IP'] ?? $_SERVER['REMOTE_ADDR'] ?? 'unknown';
            $forwarded_ip = trim(explode(',', $forwarded_ip)[0]);
            
            if (filter_var($forwarded_ip, FILTER_VALIDATE_IP) !== false) {
                $ip = $forwarded_ip;
            } else {
                $ip = 'unknown';
            }
        }
        
        // For IPv6 addresses, we'll normalize them to ensure consistency
        if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
            $ip = $this->normalizeIPv6($ip);
        }
        
        // Replace any characters that might cause issues in file paths
        $ip = preg_replace('/[^a-zA-Z0-9\.:]/', '_', $ip);
        
        return $ip;
    }
    
    private function normalizeIPv6($ip) {
        // Expand IPv6 to its full form and normalize
        $ip = inet_pton($ip);
        if ($ip !== false) {
            $hex = unpack('H*hex', $ip);
            $ip = substr(preg_replace('/([a-f0-9]{4})/', '$1:', $hex['hex']), 0, -1);
            $ip = implode(':', str_split($ip, 4));
        }
        return $ip;
    }

    private function ensureUserDirExists() {
        $user_dir = __DIR__ . '/chat_history/' . $this->user_ip;
        if (!is_dir($user_dir)) {
            mkdir($user_dir, 0755, true);
        }
    }

    public function sendRequest($user_input) {
        $prompt = $this->getCurrentPrompt();
        
        // Get recent chat history to include in the request
        $recent_chats = $this->getUserChatHistory(10); // Get last 10 conversations
        
        $messages = [
            [
                'role' => 'system',
                'content' => $prompt
            ]
        ];
        
        // Add previous chat history to the messages
        foreach ($recent_chats as $chat) {
            $messages[] = [
                'role' => 'user',
                'content' => $chat['user_input']
            ];
            $messages[] = [
                'role' => 'assistant',
                'content' => $chat['ai_response']
            ];
        }
        
        // Add the current user input
        $messages[] = [
            'role' => 'user',
            'content' => $user_input
        ];

        $data = [
            'model' => $this->selected_model,
            'messages' => $messages,
            'temperature' => 0.7
        ];

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $this->api_base_url . '/chat/completions');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $this->api_key
        ]);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);

        $response = curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($response === false) {
            throw new Exception('cURL Error: ' . curl_error($ch));
        }

        if ($http_code !== 200) {
            throw new Exception('API Error: HTTP ' . $http_code . ' - ' . $response);
        }

        $result = json_decode($response, true);

        if (json_last_error() !== JSON_ERROR_NONE) {
            throw new Exception('JSON Decode Error: ' . json_last_error_msg());
        }

        if (!isset($result['choices'][0]['message']['content'])) {
            throw new Exception('Invalid API response format');
        }

        $ai_response = trim($result['choices'][0]['message']['content']);

        $this->saveChatHistory($user_input, $ai_response);

        return $ai_response;
    }

    public function getCurrentPrompt() {
        try {
            $stmt = $this->pdo->query("SELECT prompt_text FROM prompts ORDER BY id DESC LIMIT 1");
            $result = $stmt->fetch(PDO::FETCH_ASSOC);
            
            if ($result) {
                return $result['prompt_text'];
            } else {
                return "You are a helpful AI assistant. Answer the user's questions accurately and concisely.";
            }
        } catch (Exception $e) {
            error_log("Error getting prompt: " . $e->getMessage());
            return "You are a helpful AI assistant. Answer the user's questions accurately and concisely.";
        }
    }

    private function saveChatHistory($user_input, $ai_response) {
        try {
            $stmt = $this->pdo->prepare("INSERT INTO chat_history (user_input, ai_response) VALUES (?, ?)");
            $stmt->execute([$user_input, $ai_response]);
        } catch (Exception $e) {
            error_log("Error saving chat history: " . $e->getMessage());
        }
        
        // Save to user-specific file
        $user_dir = __DIR__ . '/chat_history/' . $this->user_ip;
        $filename = $user_dir . '/chat_' . date('Y-m-d') . '.json';
        
        $chat_entry = [
            'timestamp' => date('Y-m-d H:i:s'),
            'user_input' => $user_input,
            'ai_response' => $ai_response
        ];
        
        if (file_exists($filename)) {
            $chats = json_decode(file_get_contents($filename), true);
            if (!$chats) $chats = [];
        } else {
            $chats = [];
        }
        
        $chats[] = $chat_entry;
        file_put_contents($filename, json_encode($chats, JSON_PRETTY_PRINT));
    }

    public function updatePrompt($new_prompt) {
        try {
            $stmt = $this->pdo->prepare("INSERT INTO prompts (prompt_text) VALUES (?)");
            $stmt->execute([$new_prompt]);
            return true;
        } catch (Exception $e) {
            error_log("Error updating prompt: " . $e->getMessage());
            return false;
        }
    }

    public function getChatHistory($limit = 50) {
        try {
            $stmt = $this->pdo->prepare("SELECT * FROM chat_history ORDER BY created_at DESC LIMIT ?");
            $stmt->execute([$limit]);
            return $stmt->fetchAll(PDO::FETCH_ASSOC);
        } catch (Exception $e) {
            error_log("Error getting chat history: " . $e->getMessage());
            return [];
        }
    }

    public function getUserChatHistory($limit = 10) {
        $user_dir = __DIR__ . '/chat_history/' . $this->user_ip;
        $files = glob($user_dir . '/chat_*.json');
        
        $all_chats = [];
        foreach ($files as $file) {
            $chats = json_decode(file_get_contents($file), true);
            if ($chats) {
                $all_chats = array_merge($all_chats, $chats);
            }
        }
        
        // Sort by timestamp, newest first
        usort($all_chats, function($a, $b) {
            return strtotime($b['timestamp']) - strtotime($a['timestamp']);
        });
        
        // Return only the requested number of chats
        return array_slice($all_chats, 0, $limit);
    }

    public function updateChatMessage($timestamp, $new_content, $type = 'user_input') {
        $user_dir = __DIR__ . '/chat_history/' . $this->user_ip;
        $files = glob($user_dir . '/chat_*.json');
        
        foreach ($files as $file) {
            $chats = json_decode(file_get_contents($file), true);
            if (!$chats) continue;
            
            foreach ($chats as $index => $chat) {
                if ($chat['timestamp'] === $timestamp) {
                    $chats[$index][$type] = $new_content;
                    file_put_contents($file, json_encode($chats, JSON_PRETTY_PRINT));
                    return true;
                }
            }
        }
        
        return false;
    }

    public function getText($key) {
        $texts = [
            'en' => [
                'welcome' => 'Welcome to AI Website',
                'ai_assistant_ready' => 'Your AI assistant is ready to use',
                'installation' => 'Installation',
                'database_host' => 'Database Host',
                'database_name' => 'Database Name',
                'database_username' => 'Database Username',
                'database_password' => 'Database Password',
                'api_base_url' => 'API Base URL',
                'api_key' => 'API Key',
                'ai_model' => 'AI Model',
                'install' => 'Install',
                'fill_required_fields' => 'Please fill in all required fields',
                'database_connection_failed' => 'Database connection failed',
                'installation_completed' => 'Installation completed successfully! Redirecting to main page...',
                'main_interface' => 'Main Interface',
                'your_message' => 'Your Message',
                'send_message' => 'Send Message',
                'manage_ai_prompt' => 'Manage AI Prompt',
                'current_prompt' => 'Current Prompt',
                'update_prompt' => 'Update Prompt',
                'chat_history' => 'Chat History',
                'timestamp' => 'Time',
                'user' => 'You',
                'ai' => 'AI',
                'edit' => 'Edit',
                'save' => 'Save',
                'cancel' => 'Cancel',
                'no_chat_history' => 'No chat history yet. Start a conversation below!',
                'error_updating_prompt' => 'Error updating prompt',
                'prompt_updated_successfully' => 'Prompt updated successfully',
                'please_enter_message' => 'Please enter a message',
                'please_enter_new_prompt' => 'Please enter a new prompt',
                'error' => 'Error'
            ],
            'zh' => [
                'welcome' => '欢迎来到AI网站',
                'ai_assistant_ready' => '您的AI助手已准备就绪',
                'installation' => '安装',
                'database_host' => '数据库主机',
                'database_name' => '数据库名称',
                'database_username' => '数据库用户名',
                'database_password' => '数据库密码',
                'api_base_url' => 'API基础URL',
                'api_key' => 'API密钥',
                'ai_model' => 'AI模型',
                'install' => '安装',
                'fill_required_fields' => '请填写所有必填字段',
                'database_connection_failed' => '数据库连接失败',
                'installation_completed' => '安装成功！正在跳转到主页...',
                'main_interface' => '主界面',
                'your_message' => '您的消息',
                'send_message' => '发送消息',
                'manage_ai_prompt' => '管理AI提示',
                'current_prompt' => '当前提示',
                'update_prompt' => '更新提示',
                'chat_history' => '聊天记录',
                'timestamp' => '时间',
                'user' => '您',
                'ai' => 'AI',
                'edit' => '编辑',
                'save' => '保存',
                'cancel' => '取消',
                'no_chat_history' => '暂无聊天记录。在下方开始对话！',
                'error_updating_prompt' => '更新提示时出错',
                'prompt_updated_successfully' => '提示更新成功',
                'please_enter_message' => '请输入消息',
                'please_enter_new_prompt' => '请输入新提示',
                'error' => '错误'
            ]
        ];
        
        return $texts[$this->lang][$key] ?? $key;
    }
    
    public function getAvailableModels() {
        return [
            'gpt-3.5-turbo' => 'GPT-3.5 Turbo',
            'gpt-4' => 'GPT-4',
            'gpt-4-turbo' => 'GPT-4 Turbo',
            'claude-3-sonnet' => 'Claude 3 Sonnet',
            'claude-3-opus' => 'Claude 3 Opus',
            'llama-3' => 'Llama 3',
            'mistral-7b' => 'Mistral 7B'
        ];
    }
}
?>
